<template>
  <el-dialog
    title="选择位置"
    :visible.sync="open"
    :close-on-click-modal="false"
    width="700px"
    append-to-body
    @close="cancel"
  >
    <!-- 输入框 -->
    <el-autocomplete
      class="mb10"
      style="width: 100%"
      v-model="address"
      value-key="name"
      popper-class="my-autocomplete"
      placeholder="请输入内容"
      :fetch-suggestions="querySearchAsync"
      clearable
      @select="handleSelect"
    >
      <i class="el-icon-search el-input__icon" slot="suffix"></i>
      <template slot-scope="{ item }">
        <div class="name">{{ item.name }}</div>
        <span class="addr">{{ item.district }}</span>
      </template>
    </el-autocomplete>
    <!-- 地图容器 -->
    <div ref="container" class="container"></div>
    <div class="footer" slot="footer">
      <el-button type="primary" @click="submitForm">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import AMapLoader from "@amap/amap-jsapi-loader";

let AMap = null,
  map = null,
  marker = null;

export default {
  name: "BaseAmapSelect",
  props: {
    amapKey: {
      type: String,
      default: "你的key",
    },
    amapCode: {
      type: String,
      default: "你的code",
    },
  },
  data() {
    return {
      open: false,
      latitude: null,
      longitude: null,
      address: null,
      adcode: null,
      defaultCenter: [116.41, 39.9],
    };
  },
  mounted() {
    if (!window._AMapSecurityConfig) {
      window._AMapSecurityConfig = {
        securityJsCode: this.amapCode,
      };
    }
  },
  destroyed() {
    console.log("销毁");
    map && (map = undefined);
    AMap && (AMap = undefined);
  },
  methods: {
    // 重置数据
    reset() {
      this.latitude = null;
      this.longitude = null;
      this.address = null;
      this.adcode = null;
    },
    // 打开组件
    init(options) {
      this.reset();
      this.open = true;
      // 初始化地图
      // 无需频繁初始化地图
      if (!(AMap && map)) {
        AMapLoader.load({
          key: this.amapKey, // 申请好的Web端开发者Key，首次调用 load 时必填
          version: "2.0", // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
          plugins: [
            "AMap.AutoComplete",
            "AMap.DistrictSearch",
            "AMap.Geocoder",
          ], // 需要使用的的插件列表，如比例尺'AMap.Scale'等
          AMapUI: {
            // 是否加载 AMapUI，缺省不加载
            version: "1.1", // AMapUI 缺省 1.1
            plugins: [], // 需要加载的 AMapUI ui插件
          },
          Loca: {
            // 是否加载 Loca， 缺省不加载
            version: "2.0", // Loca 版本，缺省 1.3.2
          },
        })
          .then((AMap) => {
            this.$nextTick(() => {
              this.creatAmap(AMap, options);
            });
          })
          .catch((e) => {
            console.log(e);
          });
      } else {
        // 移动视角
        if (options.cityId) {
          // 如果设置了cityId就移动至cityId
          this.getLocationByCityId(options.cityId).then((res) => {
            map.setZoomAndCenter(options.zoom, res);
          });
        } else if (options.center) {
          // 如果设置了经纬度就移动至经纬度地址
          map.setZoomAndCenter(options.zoom, options.center);
        }
        if(options.initPoint) {  // 生成回显点位
          this.creatPoint(options.initPoint);
        }
        if(options.initAddress) {  // 生成回显地址
          this.address = options.initAddress;
        }
      }
    },
    // 加载地图
    async creatAmap(aMap, options) {
      AMap = aMap;
      let pOptions = options || {};
      // 初始化参数
      let creatOptions = {
        resizeEnable: true, //窗口大小调整
        center: this.defaultCenter,
        zoom: 15,
        ...pOptions,
      };
      try {
        // 如果设置了cityId，将center改为cityId解析后的点位
        if (pOptions.cityId) {
          // console.log(pOptions.cityId);
          creatOptions.center = await this.getLocationByCityId(pOptions.cityId);
        }
      } catch (error) {
        console.log("初始化地图出错：", error);
      } finally {
        map = new AMap.Map(this.$refs.container, creatOptions);
        if(creatOptions.initPoint) {  // 生成回显点位
          this.creatPoint(creatOptions.initPoint);
        }
        if(creatOptions.initAddress) {  // 生成回显地址
          this.address = creatOptions.initAddress;
        }
        this.mapAddClick();
      }
    },
    // 给地图添加点击事件
    mapAddClick() {
      if (AMap && map) {
        let geoCoder = new AMap.Geocoder();
        map.on("click", (e) => {
          // 添加标记点
          this.creatPoint(e.lnglat);

          geoCoder.getAddress(e.lnglat, (status, res) => {
            if (status === "complete" && res.info === "OK") {
              this.address = res.regeocode.formattedAddress;
              this.adcode = res.regeocode.addressComponent.adcode;
              this.latitude = e.lnglat.lat;
              this.longitude = e.lnglat.lng;
            } else {
              this.$message({
                message: "获取位置信息失败！",
                type: "warning",
              });
            }
          });
        });
      }
    },
    // 根据cityId搜索坐标
    getLocationByCityId(cityId) {
      if (AMap && cityId) {
        return new Promise((resolve, reject) => {
          // 基础配置
          const districtSearchOptions = {
            showbiz: false,
            subdistrict: 0,
          };
          const amapDistrictSearch = new AMap.DistrictSearch(
            districtSearchOptions
          );
          amapDistrictSearch.search(cityId, (status, result) => {
            if (status === "complete" && result.info === "OK") {
              // 取数组第一个
              if (result.districtList[0]) {
                const resCenter = result.districtList[0].center;
                resolve([resCenter.lng, resCenter.lat]);
              }
            } else {
              reject(status);
            }
            // console.log('s:', status);
            // console.log('r:', result);
          });
        });
      } else {
        return Promise.reject("no AMap or no Id");
      }
    },
    // 搜索输入
    querySearchAsync(queryString, cb) {
      // 插件配置
      const autoOptions = {};
      let aMapAutoComplete = null;
      if (AMap && queryString) {
        aMapAutoComplete = new AMap.AutoComplete(autoOptions);
        // 搜索
        aMapAutoComplete.search(queryString, (status, result) => {
          if (status === "complete" && result.info === "OK") {
            cb(result.tips);
          }
          // console.log('s:', status);
          // console.log('r:', result);
        });
      }
    },
    // 选择搜索项
    handleSelect(item) {
      // console.log(item);
      if (map) {
        map.setCenter([item.location.lng, item.location.lat]);
        // 添加标记点
        this.creatPoint([item.location.lng, item.location.lat]);
        // 给表单数据
        this.address = item.district + item.address;
        this.adcode = item.adcode;
        this.latitude = item.location.lat;
        this.longitude = item.location.lng;
      }
    },
    // 生成标记点
    creatPoint(position) {
      if(marker) {
        map.remove(marker)
      }
      if(position) {
        marker = new AMap.Marker({
          position: position,
          map: map,
        });
      }
    },
    // 确认按钮
    submitForm() {
      if (this.address && this.latitude && this.longitude) {
        const data = {
          adcode: this.adcode,
          address: this.address,
          latitude: this.latitude,
          longitude: this.longitude,
        };
        this.$emit("get-address", data);
        this.open = false;
      } else {
        this.msgError("请选择地点！");
      }
    },
    // 取消按钮
    cancel() {
      // 关闭地图清空按钮
      if ((map && marker)) {
        map.remove(marker);
      }
    },
  },
};
</script>

<style lang='scss' scoped>
.container {
  width: 100%;
  height: 600px;
}

.footer {
  padding: 0 20px 10px;
}

// 自定义样式
.my-autocomplete {
  li {
    line-height: normal;
    padding: 7px;

    .name {
      text-overflow: ellipsis;
      overflow: hidden;
    }

    .addr {
      font-size: 12px;
      color: #b4b4b4;
    }

    .highlighted .addr {
      color: #ddd;
    }
  }
}
</style>
